package com.syedu.day11;

/**
 * description：java.lang.Object类,它是所有Java类的顶级父类,任何Java类都是直接或者间接继承于它的
 *
 * 本类用来演示Object类中的方法:clone(),该方法是用来进行对象克隆的
 *
 * @author Administrator
 * @date 2022/3/23 10:22
 */
public class ObjectDemo3 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Emp e1 = new Emp(11, "AA", 25,null);
        Emp e2 = new Emp(22, "BB", 26,null);
        Emp emp = new Emp(1, "jack", 30, new Emp[]{e1, e2});

        /**
         * 克隆emp员工对象
         *
         * 步骤:
         * 1.重写Object中的clone()方法,把修饰符从protected修改成public
         * 2.处理clone()的异常:java.lang.CloneNotSupportedException,直接在main()方法上使用
         *   throws CloneNotSupportedException抛出异常
         * 3.clone()方法默认返回Object类型,所以,克隆完成后可以进行强制类型转换
         * 4.让被克隆的类实现标记接口:java.lang.Cloneable,实现该接口的类就可以被克隆了
         */
        Emp newEmp = (Emp) emp.clone();
        System.out.println(newEmp);

        System.out.println("=========================================================");

        /**
         * 克隆的原理
         * 1.本体和克隆体是两个具有相同属性和行为的不同对象(内存地址不同)
         * 2.原对象和克隆对象是不公用基础属性,但是共享对象属性,
         *   即两个对象的基本类型属性(包括某些对象类型,日期,字符串...)是真正拷贝一份给新对象,所以修改A不影响B
         *   对象类型的属性时共享的,即原对象和新对象共用内存中的一份,所以修改A会影响B
         *
         *   以上结论证明了Java克隆方法默认的方式为浅层复制(基本类型复制一份,对象类型共享),
         *   如果要实现深层复制(所有属性都是拷贝一份给新对象),则必须自己写代码实现.
         */
        System.out.println(emp == newEmp);//false

        //修改克隆对象的基本属性
        newEmp.setName("rose");
        System.out.println("原本:" + emp);
        System.out.println("克隆:" + newEmp);

        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>");

        //修改克隆对象的对象属性
        newEmp.getEmps()[0].setName("CC");
        System.out.println("原本:" + emp);
        System.out.println("克隆:" + newEmp);
    }
}